﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace Medianamik.Core
{
    [TypeConverter(typeof(NodeUrlCollectionConverter))]
    public class NodeUrlCollection
    {

        public const string ROOT_ELEMENT_NAME = "urls";
        public const string URL_ELEMENT_NAME = "url";
        public const string PATH_ATT_NAME = "path";
        public const string TEMPLATE_ATT_NAME = "template";
        public const string WEBSITE_ATT_NAME = "website";
        
        private XDocument _document;
        public NodeUrlCollection()
        {
            _document = ParseDocument(null);
        }

        public NodeUrlCollection(string pDocument)
        {
            _document = ParseDocument(pDocument);
        }

        public void AddUrl(string pPath, string pTemplate, Guid pWebsite)
        {
            if (_document == null || _document.Root == null )
            {
                throw new NullReferenceException("Invalid State. Must contain a valid Xml Document.");
            }
                _document.Root.Add(new XElement(URL_ELEMENT_NAME
                                                , new XAttribute(PATH_ATT_NAME, pPath)
                                                , new XAttribute(TEMPLATE_ATT_NAME, pTemplate)
                                                , new XAttribute(WEBSITE_ATT_NAME, pWebsite)));
        }

        public IEnumerable<NodeUrlElement> Urls
        {
            get
            {
                if (_document == null || _document.Root == null)
                {
                    throw new NullReferenceException("Invalid State. Must contain a valid Xml Document.");
                }


                foreach (var url in _document.Root.Elements(URL_ELEMENT_NAME))
                {
                    yield return new NodeUrlElement()
                                     {
                                         Path = (string) url.Attribute(PATH_ATT_NAME),
                                         Template = (string)url.Attribute(TEMPLATE_ATT_NAME),
                                         Website = (Guid?)url.Attribute(WEBSITE_ATT_NAME)
                                     };
                }
            }
        }

        private static XDocument ParseDocument(string pDocument)
        {
            if(string.IsNullOrEmpty( pDocument))
            {
                return new XDocument(new XElement(ROOT_ELEMENT_NAME));
            }
            else
            {
                return XDocument.Parse(pDocument);
            }
            
        }
        
    }

    public class NodeUrlElement
    {
        public string Path { get; set; }
        public string Template { get; set; }
        public Guid? Website { get; set; }
    }

    public class NodeUrlCollectionConverter : TypeConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if(sourceType == typeof(string))
            {
                return true;
            }
            return false;
        }

        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if(value is string)
            {
                return new NodeUrlCollection((string) value);
            }

            return null;
        }
    }

}
